package com.personal.gateway.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.personal.gateway.config.FlinkVersionConfig;
import com.personal.gateway.dto.ContainerGroup;
import com.personal.gateway.entity.FlinkGatewayRoute;
import com.personal.gateway.mapper.FlinkGatewayRouteMapper;
import com.personal.gateway.service.K8sService;
import com.personal.gateway.service.WebIndexService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: FlinkGateway
 * @description:
 * @author: yangliao
 * @create: 2021-07-09 09:57
 */
@Service
public class WebIndexServiceImpl implements WebIndexService {

    @Resource
    private K8sService k8sService;

    @Resource
    private FlinkGatewayRouteMapper flinkGatewayRouteMapper;

    @Resource
    private FlinkVersionConfig flinkVersionConfig;

    @Override
    public Map<String, String> index(JSONObject obj) {
        List<ContainerGroup> containerGroups = k8sService.getContainerGroup();
        String table = initIndexHtml(containerGroups, obj);

        Map<String, String> statistical = initStatisticalInfo(containerGroups, obj);

        Map<String, String> data = new HashMap<>();
        data.put("table", table);
        data.putAll(statistical);
        return data;
    }

    @Override
    public List<ContainerGroup> jobManagerInfoList(String name) {
        List<ContainerGroup> containerGroups = k8sService.getContainerGroup();
        List<ContainerGroup> jobManager = containerGroups.stream()
                .filter(x -> x.getComponent().equals("jobmanager") && x.getApp().equals(name))
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(jobManager)) {
            return Collections.emptyList();
        }

        return jobManager;
    }

    @Override
    public List<ContainerGroup> taskManagerInfoList(String name) {
        List<ContainerGroup> containerGroups = k8sService.getContainerGroup();
        List<ContainerGroup> taskManager = containerGroups.stream()
                .filter(x -> x.getComponent().equals("taskmanager") && x.getApp().equals(name))
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(taskManager)) {
            return Collections.emptyList();
        }

        return taskManager;
    }

    @Override
    public Map<String, String> getFlinkVersion() {
        Map<String, String> flinkVersionMap = new HashMap<>(1);
        StringBuilder flinkVersionHtml = new StringBuilder();
        flinkVersionHtml.append("<option value=\"\"></option>");
        flinkVersionHtml.append("<option value=\"aaa\">aaa</option>");
        for (String flinkVersionName : new ArrayList<>(flinkVersionConfig.getAllFlinkPath().keySet())) {
            flinkVersionHtml
                    .append("<option value=\"")
                    .append(flinkVersionName)
                    .append("\">")
                    .append(flinkVersionName)
                    .append("</option>");
        }
        flinkVersionMap.put("flinkVersion", flinkVersionHtml.toString());
        return flinkVersionMap;
    }


    private String initIndexHtml(List<ContainerGroup> containerGroups, JSONObject obj) {

        StringBuilder html = new StringBuilder();

        Integer index = 0;
        for (FlinkGatewayRoute route : flinkGatewayRouteMapper.list()) {
            // JobManager必然存在，TaskManager不一定存在，或者存在多个
            // JobManager
            List<ContainerGroup> jobManager = containerGroups.stream()
                    .filter(x -> x.getComponent().equals("jobmanager") && x.getApp().equals(route.getRouteId()))
                    .collect(Collectors.toList());
            int jobManagerSize = jobManager.size();

            // TaskManager
            List<ContainerGroup> taskManager = containerGroups.stream()
                    .filter(x -> x.getComponent().equals("taskmanager") && x.getApp().equals(route.getRouteId()))
                    .collect(Collectors.toList());
            int taskManagerSize = taskManager.size();

            // 处理搜索条件
            String route_id = obj.getString("route_id");
            if (StringUtils.isNoneBlank(route_id) && !route.getRouteId().contains(route_id)) {
                continue;
            }
            String job_manager_status = obj.getString("job_manager_status");
            if (!manager_status_select(job_manager_status, jobManager)) {
                continue;
            }
            String task_manager_status = obj.getString("task_manager_status");
            if (!manager_status_select(task_manager_status, taskManager)) {
                continue;
            }

            index += 1;

            // 拼接HTML
            html.append("<tr>  ");
            html.append("  <td>").append(index).append("</td>  ");
            html.append("  <td>  ");
            html.append("      <a onclick=\"openFlink('").append(route.getRouteId()).append("',").append(jobManagerSize).append(")\" style=\"cursor:pointer;\">").append(route.getRouteId()).append("</a>  ");
            html.append("  </td>  ");
            html.append("  <td>").append(route.getProjectSummary()).append("</td>  ");
            html.append("  <td>  ");
            html.append("      <a onclick=\"openNewTab('").append(route.getProjectDetail()).append("')\" style=\"cursor:pointer;\">TAPD</a>  ");
            html.append("  </td>  ");
            html.append("  <td>  ");
            html.append("      <a onclick=\"openJobManager('").append(route.getRouteId()).append("')\" style=\"cursor:pointer;\">").append(jobManagerSize).append("</a>  ");
            html.append("  </td>  ");
            html.append("  <td>  ");
            html.append("      <a onclick=\"openTaskManager('").append(route.getRouteId()).append("')\" style=\"cursor:pointer;\">").append(taskManagerSize).append("</a>  ");
            html.append("  </td>  ");
            html.append("  <td>  ");
            if (jobManagerSize > 0) {
                html.append("      <button type=\"button\" class=\"layui-btn layui-btn-normal layui-btn-xs\">运行</button>  ");
            } else {
                html.append("      <button type=\"button\" class=\"layui-btn layui-btn-disabled layui-btn-xs\">停止</button>  ");
            }
            html.append("  </td>  ");
            html.append("  <td>  ");
            if (route.getAlarmStatus().equals(1)) {
                html.append("      <button type=\"button\" class=\"layui-btn layui-btn-normal layui-btn-xs\">启用</button>  ");
            } else {
                html.append("      <button type=\"button\" class=\"layui-btn layui-btn-disabled layui-btn-xs\">停用</button>  ");
            }
            html.append("  </td>  ");
            html.append("  <td class=\"td-status\">  ");
            html.append(route.getUserName());
            html.append("  </td>  ");
            html.append("  <td class=\"td-manage\">  ");
            html.append("    <a title=\"启动-无SAVEPOINT\" onclick=\"startNoSavePoint('").append(route.getId()).append("', '").append(route.getRouteId()).append("')\" href=\"javascript:;\" style=\"cursor:pointer;\">  ");
            html.append("      <i class=\"layui-icon\">&#xe674;</i>  ");
            html.append("    </a>  &nbsp;&nbsp;  ");
            html.append("    <a title=\"启动-使用SAVEPOINT\" onclick=\"startWithSavePoint('").append(route.getId()).append("', '").append(route.getRouteId()).append("')\" href=\"javascript:;\" style=\"cursor:pointer;\">  ");
            html.append("      <i class=\"layui-icon\">&#xe656;</i>  ");
            html.append("    </a>  &nbsp;&nbsp;  ");
            html.append("    <a title=\"停止-SAVEPOINT\" onclick=\"stopWithSavePoint('").append(route.getId()).append("', '").append(route.getRouteId()).append("')\" href=\"javascript:;\" style=\"cursor:pointer;\">  ");
            html.append("      <i class=\"layui-icon\">&#xe651;</i>  ");
            html.append("    </a>  &nbsp;&nbsp;  ");
            html.append("    <a title=\"编辑\" onclick=\"edit_project('").append(route.getId()).append("')\" href=\"javascript:;\" style=\"cursor:pointer;\">  ");
            html.append("      <i class=\"layui-icon\">&#xe642;</i>  ");
            html.append("    </a>  &nbsp;&nbsp;    ");
            html.append("    <a title=\"删除\" onclick=\"del_project('").append(route.getId()).append("', '").append(route.getRouteId()).append("')\" href=\"javascript:;\" style=\"cursor:pointer;\">  ");
            html.append("      <i class=\"layui-icon\">&#xe640;</i>  ");
            html.append("    </a>  &nbsp;&nbsp;    ");
            html.append("    <a title=\"操作历史\" onclick=\"flinkHistory('").append(route.getId()).append("', '").append(route.getRouteId()).append("')\" href=\"javascript:;\" style=\"cursor:pointer;\">  ");
            html.append("      <i class=\"layui-icon\">&#xe6b2;</i>  ");
            html.append("    </a>  &nbsp;&nbsp;    ");
            html.append("    <a title=\"监控重启\" onclick=\"monitorRestart('").append(route.getId()).append("', '").append(route.getGatewayNum()).append("', '").append(route.getRouteId()).append("')\" href=\"javascript:;\" style=\"cursor:pointer;\">  ");
            html.append("      <i class=\"layui-icon\">&#xe679;</i>  ");
            html.append("    </a>  ");
            html.append("  </td>  ");
            html.append("</tr>");
        }

        return html.toString();
    }


    private Map<String, String> initStatisticalInfo(List<ContainerGroup> containerGroups, JSONObject obj) {

        // JobManager
        List<ContainerGroup> jobManager = containerGroups.stream().filter(x -> x.getComponent().equals("jobmanager")).collect(Collectors.toList());

        // TaskManager
        List<ContainerGroup> taskManager = containerGroups.stream().filter(x -> x.getComponent().equals("taskmanager")).collect(Collectors.toList());

        Map<String, String> statistical = new HashMap<>();
        // Running Pending 未知

        statistical.put("jobManagerRunning", jobManager.stream().filter(x -> x.getPhase().equals("Running")).count() + "");
        statistical.put("taskManagerRunning", taskManager.stream().filter(x -> x.getPhase().equals("Running")).count() + "");

        statistical.put("jobManagerPending", jobManager.stream().filter(x -> x.getPhase().equals("Pending")).count() + "");
        statistical.put("taskManagerPending", taskManager.stream().filter(x -> x.getPhase().equals("Pending")).count() + "");

        statistical.put("jobManagerUnknown", jobManager.stream().filter(x -> !x.getPhase().equals("Running") && !x.getPhase().equals("Pending")).count() + "");
        statistical.put("taskManagerUnknown", taskManager.stream().filter(x -> !x.getPhase().equals("Running") && !x.getPhase().equals("Pending")).count() + "");

        return statistical;
    }

    private static boolean manager_status_select(String manager_status, List<ContainerGroup> taskManager) {
        if (StringUtils.isBlank(manager_status)) {
            return true;
        }

        if (CollectionUtils.isEmpty(taskManager)) {
            return false;
        }

        switch (manager_status) {
            case "Running":
                if (taskManager.stream().anyMatch(x -> x.getPhase().equals("Running"))) {
                    return true;
                }
                break;
            case "Pending":
                if (taskManager.stream().anyMatch(x -> x.getPhase().equals("Pending"))) {
                    return true;
                }
                break;
            case "未知":
                if (taskManager.stream().anyMatch(x -> !x.getPhase().equals("Running") && !x.getPhase().equals("Pending"))) {
                    return true;
                }
                break;
        }

        return false;
    }

}

